use actix_web::{get, post, web, HttpResponse, Responder};

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Todo {
    id: u32,
    message: String,
}

#[get("/todos")]
async fn get_all_todos() -> HttpResponse {
    let todos = vec![
        Todo {
            id: 0,
            message: String::from("foo"),
        },
        Todo {
            id: 1,
            message: String::from("bar"),
        },
    ];
    return serde_json::to_string(&todos).map_or_else(
        |err| HttpResponse::InternalServerError().body(err.to_string()),
        |b| HttpResponse::Ok().body(b),
    );
}

#[post("/todos")]
async fn post_todo(todo: web::Json<Todo>) -> impl Responder {
    log::info!("{:?}", todo);
    return HttpResponse::Ok().body(format!("id: {}, message: {}", todo.id, todo.message));
}

#[cfg(test)]
mod tests {
    use super::*;
    use actix_web::{test, App};

    #[actix_web::test]
    async fn test_get_all_todos_ok() {
        let app = test::init_service(App::new().service(self::get_all_todos)).await;
        let req = test::TestRequest::default().uri("/todos").to_request();
        let resp = test::call_service(&app, req).await;
        println!("{}", resp.status());
        assert!(resp.status().is_success());
    }
}
